/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author carlcarl
 */

/**
 * MapData使用方法：利用produceMap 丟入GoData參數即可
 */

import java.util.*;
import java.applet.Applet;

public class MapData extends Object
{
    public static final int NULL = -1, B = 0, W = 1 , OUT = 2;
    private static final int GONE = 4;

    //Step = 0是表示一開始空盤的情況 1才是第一步
    private int finalStep;
    private int nowStep;
    ArrayList<byte[][]> goMap; //一開始初始化後即有空盤的map了
    ArrayList<GoData> stepList;
    Applet applet;
        
    MapData(Applet parent)
    {
        applet = parent;
        goMap = new ArrayList<byte[][]>();
        stepList = new ArrayList<GoData>();
        finalStep = 0;
        nowStep = 0;
        
        GoData tempGoData = new GoData('W', 0, 0);
        stepList.add(tempGoData);
        
        byte[][] map = new byte [21][21];
        for(int i = 0; i < 21; i++)
        {
            for(int j = 0; j < 21; j++)
            {
                map[i][j] = NULL;
                if((i == 0) || (i == 20) || (j == 0) || (j == 20))
                {
                    map[i][j] = OUT;
                }
            }
        }
        goMap.add(map);
    }
        
    public void setFinalStep(int step)
    {
        finalStep = step;
    }
    public void setNowStep(int step)
    {
        nowStep = step;
    }
        
    public int getFinalStep()
    {
        return finalStep;
    }
    public int getNowStep()
    {
        return nowStep;
    }

    public void deleteLastStepData()
    {
        //int finalStep = vMapData.getFinalStep();
        stepList.remove(finalStep);
        goMap.remove(finalStep);
        finalStep--;
    }

    /**
     *
     * @回傳現在這一步的棋譜map
     */
    public byte[][] getGoMap(int step)
    {
        return goMap.get(step);
    }

    /**
     *
     * @回傳現在這一步棋的顏色 黑或白
     */
    public int getStepPositionColor(int step)
    {
        return stepList.get(step).getColor();
    }

    public int getStepPositionX(int step)
    {
        return stepList.get(step).getX();
    }
    public int getStepPositionY(int step)
    {
        return stepList.get(step).getY();
    }

    public void setMap(int step, byte[][] map)
    {
        for(int i = 0; i < 21; i++)
        {
            System.arraycopy(map[i], 0, goMap.get(step)[i], 0, 21);
        }
    }

    public void produceMap(GoData g)
    {   
        byte[][] map = new byte[21][21];
        copy(goMap.get(finalStep), map);
        
        byte temp;
        if(g.getColor() == 'B')
        {
            temp = B;
        }
        else temp = W;
        
        map[g.getX()][g.getY()] = temp;

        findDead(map, g.getX(), g.getY(), 1 - temp);
        if(detectDeadMove(map, g.getX(), g.getY(), temp) == true)
                return ;
        stepList.add(g);
        goMap.add(map);
        finalStep++;
    }
    private void copy(byte[][] source, byte[][] target)
    {
        for(int i = 0; i < 21; i++)
        {
            System.arraycopy(source[i], 0, target[i], 0, 21);
        }
    }

    private boolean detectDeadMove(byte[][] map, int x, int y, int color)
    {
        byte[][] m = new byte[21][21];
        copy(map, m);
        Bool current = new Bool(true);
        recursiveFind(m, x, y, color, current);
        return current.getBool();
    }

    private void findDead(byte[][] map, int x, int y, int color)
    {
        Bool up = new Bool(true);
        Bool down = new Bool(true); 
        Bool left = new Bool(true); 
        Bool right = new Bool(true);
        
        byte[][] tempMap = new byte[21][21];
        copy(map, tempMap);
        
        if(map[x][y-1] == color)
        {
            recursiveFind(tempMap, x, y - 1, color, up);
            if(up.equals(true))
            {
                recursiveDelete(map, x, y - 1, color);
                copy(map, tempMap);
            }
            else copy(map, tempMap);
        }
        
        if(map[x][y+1] == color)
        {
            recursiveFind(tempMap, x, y + 1, color, down);
            if(down.equals(true))
            {
                recursiveDelete(map, x, y + 1, color);
                copy(map, tempMap);
            }
            else copy(map, tempMap);
        }
        
        if(map[x-1][y] == color)
        {
            recursiveFind(tempMap, x - 1, y, color, left);
            if(left.equals(true))
            {
                recursiveDelete(map, x - 1, y, color);
                copy(map, tempMap);
            }
            else copy(map, tempMap);
        }
        
        if(map[x+1][y] == color)
        {
            recursiveFind(tempMap, x + 1, y, color, right);
            if(right.equals(true))
            {
                recursiveDelete(map, x + 1, y, color);
                copy(map, tempMap);
            }
            else copy(map, tempMap);
        }
    }
    private void recursiveFind(byte [][] m, int x, int y, int color, Bool dead) // m是暫存的map
    {
        m[x][y] += GONE; //表示已經被找過了
        
        if(m[x+1][y] == color)
        {
            recursiveFind(m, x + 1, y, color, dead);
        }
        else if(m[x+1][y] == NULL)
        {
            dead.setBool(false);
            return;
        }
        if(m[x][y+1] == color)
        {
            recursiveFind(m, x, y + 1, color, dead);
        }
        else if(m[x][y+1] == NULL)
        {
            dead.setBool(false);
            return;
        }
        
        if(m[x-1][y] == color)
        {
            recursiveFind(m, x - 1, y, color, dead);
        }
        else if(m[x-1][y] == NULL)
        {
            dead.setBool(false);
            return;
        }
        if(m[x][y-1] == color)
        {
            recursiveFind(m, x, y - 1, color, dead);
        }
        else if(m[x][y-1] == NULL)
        {
            dead.setBool(false);
            return;
        }
    }
    private void recursiveDelete(byte [][] map, int x, int y, int color)
    {
        map[x][y] = NULL;
        
        if(map[x+1][y] == color)
        {
            recursiveDelete(map, x + 1, y, color);
        }
        if(map[x][y+1] == color)
        {
            recursiveDelete(map, x, y + 1, color);
        }
        if(map[x-1][y] == color)
        {
            recursiveDelete(map, x - 1, y, color);
        }
        if(map[x][y-1] == color)
        {
            recursiveDelete(map, x, y - 1, color);
        }
    }   
    
}
